﻿using System;
using System.IO;
using System.Reflection;
using ICSharpCode.SharpZipLib.Zip;
using System.Collections;

namespace RibbonEditor.Managers
{
    /// <summary>
    /// Class allowing to unzip archive
    /// </summary>
    class ZipManager
    {
        public static void ExtractFilesContentFromZip(byte[] zipFile, string targetFolder)
        {
            Stream zipStream = new MemoryStream(zipFile);

            ExtractFilesContentFromZip(zipStream, targetFolder);
        }

        public static void ExtractFilesContentFromZip(Stream stream, string targetFolder)
        {
            DirectoryInfo currentDirectory = new FileInfo(Assembly.GetExecutingAssembly().FullName).Directory;
            string currentPath = currentDirectory.FullName;

            if (!Directory.Exists(currentPath + "\\" + targetFolder))
            {
                Directory.CreateDirectory(currentPath + "\\" + targetFolder);
            }
             
            currentDirectory = new DirectoryInfo(currentPath + "\\" + targetFolder);
            currentPath = currentDirectory.FullName;

            using (ZipInputStream s = new ZipInputStream(stream))
            {
                ZipEntry theEntry;

                while ((theEntry = s.GetNextEntry()) != null)
                {
                    string directoryName = Path.GetDirectoryName(theEntry.Name);
                    string fileName = Path.GetFileName(theEntry.Name);

                    // create directory
                    if (directoryName.Length > 0 && directoryName != currentDirectory.Name)
                    {
                        // Do nothing
                        Directory.CreateDirectory(currentPath + "\\" + directoryName);
                        currentDirectory = new DirectoryInfo(currentPath + "\\" + directoryName);
                    }

                    currentPath = currentDirectory.FullName;

                    if (fileName != String.Empty)
                    {
                        using (MemoryStream mStream = new MemoryStream())
                        {
                            int size = 2048;
                            byte[] data = new byte[2048];
                            while (true)
                            {
                                size = s.Read(data, 0, data.Length);
                                if (size > 0)
                                {
                                    mStream.Write(data, 0, size);
                                }
                                else
                                {
                                    break;
                                }
                            }

                            mStream.Seek(0, SeekOrigin.Begin);

                            using (StreamWriter writer = new StreamWriter(currentPath + "\\" + fileName))
                            {
                                using (StreamReader reader = new StreamReader(mStream))
                                {
                                    writer.Write(reader.ReadToEnd());
                                }
                            }
                        }
                    }
                }
            }
        }

        public static void ZipFiles(string inputFolderPath, string outputPathAndFile)
        {
            FastZip fz = new FastZip();
            fz.CreateZip(outputPathAndFile, inputFolderPath, true, "");
        }

        private static ArrayList GenerateFileList(string Dir)
        {
            ArrayList fils = new ArrayList();
            bool Empty = true;
            foreach (string file in Directory.GetFiles(Dir)) // add each file in directory
            {
                fils.Add(file);
                Empty = false;
            }

            if (Empty)
            {
                if (Directory.GetDirectories(Dir).Length == 0)
                // if directory is completely empty, add it
                {
                    fils.Add(Dir + @"/");
                }
            }

            foreach (string dirs in Directory.GetDirectories(Dir)) // recursive
            {
                foreach (object obj in GenerateFileList(dirs))
                {
                    fils.Add(obj);
                }
            }
            return fils; // return file list
        }
    }
}
